/***************************************************************************
 *   Copyright (C) 2010 by Oleg Goncharov  *
 *   $EMAIL$                           *                          
 *                                                                         *
 *   This file is part of ChessVision.                                     *
 *                                                                         *
 *   ChessVision is free software; you can redistribute it and/or modify   *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 *   This program is distributed in the hope that it will be useful,       *
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
 *   GNU General Public License for more details.                          *
 *                                                                         *
 *   You should have received a copy of the GNU General Public License     *
 *   along with this program; if not, write to the                         *
 *   Free Software Foundation, Inc.,                                       *
 *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
 ***************************************************************************/
#include <opencv/cv.h>
#include <opencv/highgui.h>
#include <cmath>

#include "ccornerdetector.h"

namespace Chess {

bool CCornerDetector::DetectChessboard(IplImage * img, CBoardCells& cells) {
	bool ret;
	float dx = 0, dy = 0;
	float mx = 0, my = 0;
	CvSize size = cvGetSize(img);
	CvPoint2D32f corners[49];
	int ncorners;
	SBoardPosition bp;
	
	IplImage * grey = cvCreateImage(size, IPL_DEPTH_8U, 1);
	cvCvtColor(img, grey, CV_BGR2GRAY);
	
	ret = (bool) cvFindChessboardCorners(grey, cvSize(7,7), corners, &ncorners, CV_CALIB_CB_ADAPTIVE_THRESH );
	
	if (ret) {
		bp.h = 0;
		bp.x = 0;
		bp.y = 0;
		for(int i = 0; i < 6; i++) {
			for(int j = 0; j < 6; j++) {
				bp.h += dist(corners[i*7 + j], corners[i*7 + j + 1]);
				bp.h += dist(corners[i*7 + j], corners[(i+1)*7 + j]);
			}
			dx += corners[i*7 + 6].x - corners[i*7].x;
			dy += corners[i*7 + 6].y - corners[i*7].y;
		}
		dx /= 6;
		dy /= 6;
		
		for(int i = 0; i < 49; i++) {
			bp.x += corners[i].x; 
			bp.y += corners[i].y;
		}
		
		bp.x = bp.x / 49;
		bp.y = bp.y / 49;
		bp.h /= 72;
		bp.teta = atan2(dy, dx);
		
		if (Integral(grey, bp, int(bp.h/2)) < 0) bp.teta += M_PI/2.0f;
		
		cells.Init(bp);
	}
	
	cvReleaseImage(&grey);
	
	return ret;
}

}

